package AuxFunctions;

import java.util.HashSet;
import java.util.Set;

import studentsGA.StudentGene;
import studentsGA.StudentsAlgorithm;
import GA.Chromosome;
import GA.Gene;

public class ChromosomeFun {

	public static boolean containsGen(Gene g, Gene[] gl){
		for (int i = 0; i < gl.length; i++)
			if (g.equals(gl[i])) return true;
		return false;
	}
	
	/** Returns if gl contains g between [begin, end) **/
	public static boolean containsGen(Gene g, Gene[] gl, int begin, int end){
		for (int i = begin; i < end; i++)
			if (g.equals(gl[i])) return true;
		return false;
	}
	
	// Returns if pos contains aux for 0 to index
	public static boolean contains(int[] pos, int index, int aux){
		for (int i = 0; i < index; i++)
			if (pos[i] == aux) return true;
		return false;
	}
	
	/** Returns gene's position in chromosome if it's found between [xmin, xmax]
	 *  else -1 ***/
	public static int position(Gene gene, Chromosome chromosome, int xmin, int xmax) {
		boolean found = false;
		int i = xmin;
		while (!found && i <= xmax){
			found = gene.equals(chromosome.getGene(i));
			i++;
		}
		
		if (found)
			return i-1;
		else
			return -1;
	}
	
	
	public static Chromosome checkIntegrity(Chromosome child){
		// Aux set to ease the algorithm
		Set<Integer> l = new HashSet<Integer>();
		for (int i = 0; i < StudentsAlgorithm.N; i++)
			l.add(i);
		// Remove repeated gens on the child
		for (int i = 0; i < child.getChromosomeLenght(); i++)
			if (child.getGene(i).id >= 0){ 
				if (AuxFunctions.ChromosomeFun.containsGen(child.getGene(i), child.getGene(), 0, i))
					child.setGene(i, null);
				else
					l.remove((Integer)child.getGene(i).id);
			}
		
		// Check if there is less "empty" alumns than it should be
		Object[] index = l.toArray();
		int empty = 0;
		for (int i = 0; i < child.getChromosomeLenght(); i++)
			if (child.getGene(i) == null)
				empty++;
		if (empty > index.length)
			for (int i = 0; i < child.getChromosomeLenght(); i++)
				if (child.getGene(i) == null){
					child.setGene(i, new StudentGene(-1));
					empty--;
					if (empty == index.length)
						break;
				}
				
		// Insert chromosomes left (if is there any)
		int k = 0;
		if (k < index.length)
			for (int i = 0; i < child.getChromosomeLenght(); i++)
				if (child.getGene(i) == null){
					child.setGene(i, new StudentGene((Integer)index[k]));
					k++;
				}				
		
		// If there is any id left, it's because we got too many id < 0
		if (k < index.length)
			for (int i = 0; i < child.getChromosomeLenght(); i++)
				if (child.getGene(i).id < 0){
					child.setGene(i, new StudentGene((Integer)index[k]));
					k++;
					if (k >= index.length)
						break;	// there's no more indexs to assign
				}
					
		return child;
	}
}
